---
title: Rolling Out New Allowed Types
sidebar_position: 3
---

# Rolling Out New Allowed Types

This guide shows how to safely add a new [TreeNodeSchema](../../../api/fluid-framework/treenodeschema-typealias) to an existing [AllowedTypes](../../../api/tree/allowedtypes-typealias) in a [SharedTree](../index.mdx) schema without breaking [forwards compatibility](./index.mdx#forwards-compatibility) with existing applications.

Directly adding a new node type to an existing field would cause old clients to be unable to load documents whose schema contain the new type, breaking them immediately.
The following process stages changes to introduce a new allowed type in a non-breaking way.

## Step-by-Step Guide

The example below walks through the process of adding string support to a field that previously only supported numbers.
The full code can be found in our [tests](https://github.com/microsoft/FluidFramework/blob/main/packages/dds/tree/src/test/simple-tree/api/stagedSchemaUpgrade.spec.ts).
There are some differences because this guide describes the example as a real scenario involving code deployments while the full code example uses test utilities to emulate this.

We start with a schema that only supports numbers and initialize the tree with it:
```typescript
// Schema A: only number allowed
const schemaA = SchemaFactoryBeta.optional([SchemaFactoryBeta.number]);

// initialize with schema A
const configA = new TreeViewConfiguration({
    schema: schemaA,
});
const viewA = treeA.viewWith(configA);
viewA.initialize(5);
synchronizeTrees();
```

### Step 1: Define and Stage the New Allowed Type

To add support for reading strings, we import the alpha APIs and use [`staged`](../../../api/fluid-framework/schemafactorybeta-class.md) to mark the new allowed type:

```typescript
// Schema B: number or string (string is staged)
const schemaB = SchemaFactoryBeta.optional(SchemaFactoryBeta.types([
    SchemaFactoryBeta.number,
    SchemaFactoryBeta.staged(SchemaFactoryBeta.string),
]));
```

### Step 2: Upgrade the Schema to Deploy Reading Support

We can now deploy `schemaB` to clients as a complete replacement to `schemaA`.
At this point, new clients will be able to read documents containing strings and old clients will not.
This is safe because no clients have the ability to insert strings into the document.

```typescript
// view second tree with schema B
const configB = new TreeViewConfiguration({
    schema: schemaB,
});
const viewB = treeB.viewWith(configB);
// check view B can read the document
assert.equal(viewB.compatibility.canView, true);

// check view B cannot write strings to the root
assert.throws(() => {
    viewB.root = "test";
});
```

For this schema change, the schema does not need to be [upgraded](./index.mdx#schema-upgrade-process) because [`staged`](../../../api/fluid-framework/schemafactorybeta-class.md) allowed types are removed from stored schemas.
Upgrading the schema would result in a noop.

### Step 3: Wait for Client Saturation

Ensure all clients in the deployment have the staged support before proceeding.
Monitor the deployment to confirm coverage.

See the [staged rollouts](./index.mdx#staged-rollouts) section for more details on this step.

### Step 4: Upgrade to Allow Inserting the New Allowed Type

Once client saturation has been reached, remove the [`staged()`](../../../api/fluid-framework/schemafactorybeta-class.md) wrapper from the new allowed type and call `upgradeSchema` to make a change to the stored schema:

```typescript
// Schema C: number or string, both fully allowed
const schemaC = SchemaFactoryBeta.optional([
    SchemaFactoryBeta.number,
    SchemaFactoryBeta.string,
]);

// view third tree with schema C
const configC = new TreeViewConfiguration({
    schema: schemaC,
});
const viewC = treeC.viewWith(configC);
assert.equal(viewC.compatibility.canView, false);
assert.equal(viewC.compatibility.canUpgrade, true);
// upgrade to schema C and change the root to a string
viewC.upgradeSchema();
viewC.root = "test";
synchronizeTrees();
```

Any client code changes to add functionality for inserting the new allowed type can also be deployed in this step.

## See Also

- [`SchemaStaticsBeta.staged()` API](../../../api/fluid-framework/schemafactorybeta-class.md) - API documentation
- [Schema Definition](../schema-definition.mdx) - How to define schemas
- [Node Types](../node-types.mdx) - Understanding different node types
